/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2014-2019.
 * Description: main header for idump, including some macro, function, struct defines
 * Author: nixiaoming
 * Create: 2014-6-18
 */

#ifndef _LINUX_IDUMP_H_
#define _LINUX_IDUMP_H_

#ifdef CONFIG_RTOS_IDUMP
#include <linux/binfmts.h>
#include <linux/task_struct_extend.h>
#include <linux/idump_debug.h>
#include <linux/rtos_mm_types.h>

struct rtos_coredump_params {
	struct coredump_params cprm;
	unsigned int dump_filter_type;
#if defined(CONFIG_RTOS_IDUMP_FORCE) || defined(CONFIG_RTOS_IDUMP_TRIGGER)
	struct task_struct *task;
#endif
};

extern void get_rtos_task_stack(unsigned long clone_flags, unsigned long sp,
		struct task_struct *p);

static inline struct rtos_coredump_params *coredump_params_to_rtos(struct coredump_params *cprm)
{
	return container_of(cprm, struct rtos_coredump_params, cprm);
}

enum  {
	FILTER_CORE_DUMP, /* linux coredump */
	FILTER_SMART_DUMP, /* rtos smart_dump */
	FILTER_DUMP_TYPE_NUM,
};

#define IDUMP_USED_STACK  0
#define IDUMP_FULL_STACK  (0xffffffff)
#else /* !CONFIG_RTOS_IDUMP */
#define get_rtos_task_stack(x, y, z) do { } while (0)
#endif /* CONFIG_RTOS_IDUMP */

/* num of coredump_trigger interface */
#ifdef CONFIG_RTOS_IDUMP_TRIGGER
#define IDUMP_TRIGGER_ENT (1)
#else
#define IDUMP_TRIGGER_ENT (0)
#endif /* CONFIG_RTOS_IDUMP_TRIGGER */

#ifdef CONFIG_RTOS_IDUMP_FORCE
/* num of coredump_force interface */
#define IDUMP_FORCE_ENT (1)
extern void check_idump_trigger(struct ksignal *ksig);
#else
#define check_idump_trigger(x) do { } while (0)
#define IDUMP_FORCE_ENT (0)
#endif /* CONFIG_RTOS_IDUMP_FORCE */

#if defined(CONFIG_RTOS_IDUMP_FORCE) || defined(CONFIG_RTOS_IDUMP_TRIGGER)
#define IDUMP_TRIGGER_ENABLE 1

#define IDUMP_TRIGGER_NAME "coredump_trigger"
#define IDUMP_FORCE_NAME "coredump_force"
#define IDUMP_TIMEOUT "coredump_timeout"

/* num of coredump_timeout interface */
#define IDUMP_TIMEOUT_ENT (1)

/* count ignore dentrys of idump trigger */
#define MAX_IGN_ENTS (IDUMP_TIMEOUT_ENT + \
			IDUMP_FORCE_ENT + \
			IDUMP_TRIGGER_ENT)

enum {
	ALLOW_IDUMP = 0,
	FATAL_SIGNAL_PENDING = 1,
	SIGNAL_GROUTP_EXIT,
	TASK_IS_STOPPED_OR_TRACED,
	TASK_IS_DEAD,
	UNINTERRUPTIBLE,
	TASK_FLAGS_EXIT,
	MM_NULL,
	BEING_COREDUMP,
	NO_ALLOW_CASE_MAX,
};

extern unsigned int idump_trigger_enable;
extern unsigned int idump_trigger_enable_by_proc;
extern bool task_being_idump(struct task_struct *tsk);
extern int task_allow_idump(struct task_struct *tsk);
extern int do_dump_trigger(struct task_struct *task);
extern void do_idump_stop(void);
extern void set_idump_trigger_enable(void);

/*
 * when idump_trigger_enable != IDUMP_TRIGGER_ENABLE,
 * IDUMP_TRIGGER_NAME,IDUMP_FORCE_NAME and IDUMP_TIMEOUT
 * should ignore when exec 'ls' in /proc/pid or call open()
 * to these files.
 */
static inline bool is_idump_trigger_ent_ignore(const unsigned char *name)
{
	set_idump_trigger_enable();
	return ((idump_trigger_enable != IDUMP_TRIGGER_ENABLE) &&
		(!strcmp(name, IDUMP_TRIGGER_NAME) ||
		 !strcmp(name, IDUMP_FORCE_NAME) ||
		 !strcmp(name, IDUMP_TIMEOUT)));
}

/*
* when idump_trigger_enable != IDUMP_TRIGGER_ENABLE, dentrys of idump
* trigger in /proc/pid should be ignored. ctx->pos and nents should
* reduce those dentrys at the same time.
*/
static inline unsigned int idump_ignore_ents(void)
{
	if (idump_trigger_enable == IDUMP_TRIGGER_ENABLE)
		return 0;
	return MAX_IGN_ENTS;
}

static inline struct task_struct *coredump_params_to_task(struct coredump_params *cprm)
{
	struct rtos_coredump_params *rtos_cprm = coredump_params_to_rtos(cprm);
	return rtos_cprm->task;
}

#else
static inline unsigned int idump_ignore_ents(void)
{
	return  0;
}

#endif /* CONFIG_RTOS_IDUMP_FORCE || CONFIG_RTOS_IDUMP_TRIGGER */

#endif /* _LINUX_IDUMP_H_ */
